//package org.example.controller;
//
//import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.Parameter;
//import io.swagger.v3.oas.annotations.media.Content;
//import io.swagger.v3.oas.annotations.media.Schema;
//import io.swagger.v3.oas.annotations.responses.ApiResponse;
//import io.swagger.v3.oas.annotations.tags.Tag;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.HttpStatus;
//import org.springframework.http.MediaType;
//import org.springframework.http.ResponseEntity;
//import org.springframework.web.bind.annotation.*;
//import org.springframework.web.multipart.MultipartFile;
//
//import javax.imageio.ImageIO;
//import java.awt.*;
//import java.awt.image.BufferedImage;
//import java.io.File;
//import java.io.IOException;
//import java.nio.file.Files;
//import java.nio.file.Path;
//import java.nio.file.Paths;
//import java.util.Arrays;
//import java.util.Comparator;
//
//@RestController
//@RequestMapping("/api/images")
//@Tag(name = "图片管理接口", description = "提供图片上传、获取和列表展示的接口," +
//        "实现当图片数量达到 20 张时，" +
//        "删除旧的图片并添加新的图片，同时更新所有图片的编号，")
//public class ImageController {
//
//    private static final String UPLOAD_DIR = "uploads";
//    private static final int MAX_IMAGE_COUNT = 20;
//    // 定义目标宽度和高度
//    private static final int TARGET_WIDTH = 800;
//    private static final int TARGET_HEIGHT = 600;
//
//    /**
//     * 处理图片上传的 POST 请求
//     * @param file 前端表单中名为 "image" 的文件，使用 @RequestParam 注解指定参数名
//     * @return 返回一个包含上传结果信息的 ResponseEntity 对象
//     */
//    @PostMapping
//    @Operation(summary = "上传图片", description = "上传一张图片，并将其按指定大小存储，返回图片的访问路径",
//            responses = {
//                    @ApiResponse(responseCode = "200", description = "图片上传成功", content = @Content(schema = @Schema(implementation = String.class))),
//                    @ApiResponse(responseCode = "500", description = "图片上传失败", content = @Content(schema = @Schema(implementation = String.class)))
//            })
//    public ResponseEntity<String> uploadImage(@Parameter(description = "要上传的图片文件", required = true) @RequestParam("image") MultipartFile file) {
//        File uploadDir = new File(UPLOAD_DIR);
//        if (!uploadDir.exists()) {
//            uploadDir.mkdirs();
//        }
//
//        // 获取当前目录下所有以 image 开头且以 .jpg 结尾的文件
//        File[] existingFiles = uploadDir.listFiles(new java.io.FilenameFilter() {
//            @Override
//            public boolean accept(File dir, String name) {
//                return name.startsWith("image") && name.endsWith(".jpg");
//            }
//        });
//
//        int newNumber = 1;
//        if (existingFiles != null && existingFiles.length > 0) {
//            // 按编号升序排序
//            Arrays.sort(existingFiles, new Comparator<File>() {
//                @Override
//                public int compare(File f1, File f2) {
//                    String fileName1 = f1.getName();
//                    String fileName2 = f2.getName();
//                    int number1 = Integer.parseInt(fileName1.substring(5, fileName1.length() - 4));
//                    int number2 = Integer.parseInt(fileName2.substring(5, fileName2.length() - 4));
//                    return number1 - number2;
//                }
//            });
//
//            if (existingFiles.length >= MAX_IMAGE_COUNT) {
//                // 删除编号最小（最旧）的图片
//                File oldestFile = existingFiles[0];
//                oldestFile.delete();
//            }
//
//            // 获取当前最大编号
//            String lastFileName = existingFiles[existingFiles.length - 1].getName();
//            newNumber = Integer.parseInt(lastFileName.substring(5, lastFileName.length() - 4)) + 1;
//        }
//
//        String newFileName = "image" + newNumber + ".jpg";
//        Path filePath = Paths.get(UPLOAD_DIR, newFileName);
//
//        try {
//            // 读取原始图片
//            BufferedImage originalImage = ImageIO.read(file.getInputStream());
//            // 缩放图片
//            BufferedImage resizedImage = resizeImage(originalImage, TARGET_WIDTH, TARGET_HEIGHT);
//            // 将缩放后的图片保存到指定路径
//            File output = filePath.toFile();
//            ImageIO.write(resizedImage, "jpg", output);
//
//            return ResponseEntity.ok("图片上传成功，访问路径: /api/images/" + newFileName);
//        } catch (IOException e) {
//            e.printStackTrace();
//            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("图片上传失败");
//        }
//    }
//
//    /**
//     * 缩放图片的方法
//     * @param originalImage 原始图片
//     * @param targetWidth 目标宽度
//     * @param targetHeight 目标高度
//     * @return 缩放后的图片
//     */
//    private BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
//        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
//        Graphics2D graphics2D = resizedImage.createGraphics();
//        graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
//        graphics2D.dispose();
//        return resizedImage;
//    }
//
//    /**
//     * 处理获取图片的 GET 请求
//     * @param fileName 路径参数，指定要获取的图片的文件名
//     * @return 返回一个包含图片二进制数据的 ResponseEntity 对象
//     */
//    @GetMapping("/{fileName}")
//    @Operation(summary = "获取图片,类型：JPG 接收格式：二进制", description = "根据文件名获取指定图片的二进制数据，让数字越大的图片越旧，请求时，请求的文件名为image+数字 例如 image1",
//            responses = {
//                    @ApiResponse(responseCode = "200", description = "成功获取图片", content = @Content(mediaType = MediaType.IMAGE_JPEG_VALUE)),
//                    @ApiResponse(responseCode = "404", description = "图片未找到", content = @Content)
//            })
//    public ResponseEntity<byte[]> getImage(@Parameter(description = "要获取的图片文件名", required = true) @PathVariable String fileName) {
//        Path filePath = Paths.get(UPLOAD_DIR, fileName);
//        File file = filePath.toFile();
//        if (file.exists() && file.isFile()) {
//            try {
//                byte[] imageBytes = Files.readAllBytes(filePath);
//                HttpHeaders headers = new HttpHeaders();
//                headers.setContentType(MediaType.IMAGE_JPEG);
//                headers.setContentLength(imageBytes.length);
//                return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
//    }
//
//    /**
//     * 获取所有图片的列表，返回文件名数组
//     * @return 返回包含所有图片文件名的响应实体
//     */
//    @GetMapping("/list")
//    @Operation(summary = "获取所有图片列表", description = "返回存储的所有图片的文件名数组",
//            responses = {
//                    @ApiResponse(responseCode = "200", description = "成功获取图片列表", content = @Content(schema = @Schema(implementation = String[].class))),
//                    @ApiResponse(responseCode = "404", description = "未找到图片", content = @Content)
//            })
//    public ResponseEntity<String[]> listImages() {
//        File uploadDir = new File(UPLOAD_DIR);
//        if (uploadDir.exists() && uploadDir.isDirectory()) {
//            String[] imageFiles = uploadDir.list(new java.io.FilenameFilter() {
//                @Override
//                public boolean accept(File dir, String name) {
//                    return name.startsWith("image") && name.endsWith(".jpg");
//                }
//            });
//            if (imageFiles != null) {
//                return ResponseEntity.ok(imageFiles);
//            }
//        }
//        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
//    }
//}

package org.example.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;

@RestController
@RequestMapping("/api/images")
@Tag(name = "图片管理接口", description = "提供图片上传、获取和列表展示的接口," +
        "实现当图片数量达到 20 张时，" +
        "删除旧的图片并添加新的图片，同时更新所有图片的编号，新图片编号小，旧图片编号大")
public class ImageController {

    private static final String UPLOAD_DIR = "uploads";
    private static final int MAX_IMAGE_COUNT = 20;
    // 定义目标宽度和高度
    private static final int TARGET_WIDTH = 800;
    private static final int TARGET_HEIGHT = 600;

    /**
     * 处理图片上传的 POST 请求
     * @param file 前端表单中名为 "image" 的文件，使用 @RequestParam 注解指定参数名
     * @return 返回一个包含上传结果信息的 ResponseEntity 对象
     */
    @PostMapping
    @Operation(summary = "上传图片", description = "上传一张图片，并将其按指定大小存储，返回图片的访问路径",
            responses = {
                    @ApiResponse(responseCode = "200", description = "图片上传成功", content = @Content(schema = @Schema(implementation = String.class))),
                    @ApiResponse(responseCode = "500", description = "图片上传失败", content = @Content(schema = @Schema(implementation = String.class)))
            })
    public ResponseEntity<String> uploadImage(@Parameter(description = "要上传的图片文件", required = true) @RequestParam("image") MultipartFile file) {
        File uploadDir = new File(UPLOAD_DIR);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
//        这段代码通过 FilenameFilter 实现了对指定目录下文件的筛选，仅保留符合命名规则的 .jpg 图片文件，为后续的文件编号管理（
//        如排序、重命名、删除旧文件）提供了数据基础。在实际开发中，需结合空指针处理和更严谨的文件类型校验来增强代码健壮性。
//
        // 获取当前目录下所有以 image 开头且以 .jpg 结尾的文件
        File[] existingFiles = uploadDir.listFiles(new java.io.FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.startsWith("image") && name.endsWith(".jpg");
            }
        });

        if (existingFiles != null) {
            // 按编号降序排序
            Arrays.sort(existingFiles, new Comparator<File>() {
                @Override
                public int compare(File f1, File f2) {
                    String fileName1 = f1.getName();
                    String fileName2 = f2.getName();
                    int number1 = Integer.parseInt(fileName1.substring(5, fileName1.length() - 4));
                    int number2 = Integer.parseInt(fileName2.substring(5, fileName2.length() - 4));
                    return number2 - number1;
                }
            });

            if (existingFiles.length >= MAX_IMAGE_COUNT) {
                // 删除编号最大（最旧）的图片
                File oldestFile = existingFiles[existingFiles.length - 1];
                oldestFile.delete();
            }

            // 对剩余图片编号加 1
            // 对剩余图片编号加 1
            for (File existingFile : existingFiles) {
                // 获取当前文件的原始文件名，例如 "image1.jpg"
                String oldFileName = existingFile.getName();
                // 从文件名中提取编号部分，假设文件名格式为 "imageX.jpg"，提取出 X 并转换为整数
                // 这里 substring(5, oldFileName.length() - 4) 是因为 "image" 长度为 5，".jpg" 长度为 4
                int oldNumber = Integer.parseInt(oldFileName.substring(5, oldFileName.length() - 4));
                // 生成新的文件名，将原编号加 1 后重新组合成新的文件名，例如 "image2.jpg"
                String newFileName = "image" + (oldNumber + 1) + ".jpg";
                // 将当前文件对象转换为 Path 对象，Path 对象用于表示文件或目录的路径
                Path oldFilePath = existingFile.toPath();
                // 根据上传目录和新文件名创建新的 Path 对象，表示文件要移动到的新路径
                Path newFilePath = Paths.get(UPLOAD_DIR, newFileName);
                try {
                    // 使用 Files 类的 move 方法将文件从旧路径移动到新路径，实现文件重命名
                    Files.move(oldFilePath, newFilePath);
                } catch (IOException e) {
                    // 如果移动文件过程中出现 I/O 异常，打印异常堆栈信息
                    e.printStackTrace();
                    // 返回一个 HTTP 500 状态码的响应，表示服务器内部错误，并携带错误信息
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("图片编号更新失败");
                }
            }
        }

        String newFileName = "image1.jpg";
        Path filePath = Paths.get(UPLOAD_DIR, newFileName);

        try {
            // 读取原始图片
            BufferedImage originalImage = ImageIO.read(file.getInputStream());
            // 缩放图片
            BufferedImage resizedImage = resizeImage(originalImage, TARGET_WIDTH, TARGET_HEIGHT);
            // 将缩放后的图片保存到指定路径
            File output = filePath.toFile();
            ImageIO.write(resizedImage, "jpg", output);

            return ResponseEntity.ok("图片上传成功，访问路径: /api/images/" + newFileName);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("图片上传失败");
        }
    }

    /**
     * 缩放图片的方法
     * @param originalImage 原始图片
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @return 缩放后的图片
     */
    private BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = resizedImage.createGraphics();
        graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
        graphics2D.dispose();
        return resizedImage;
    }

    /**
     * 处理获取图片的 GET 请求
     * @param fileName 路径参数，指定要获取的图片的文件名
     * @return 返回一个包含图片二进制数据的 ResponseEntity 对象
     */
    @GetMapping("/{fileName}")
    @Operation(summary = "获取图片,类型：JPG 接收格式：二进制", description = "根据文件名获取指定图片的二进制数据，让数字越小的图片越新，请求时，请求的文件名为image+数字 例如 image1",
            responses = {
                    @ApiResponse(responseCode = "200", description = "成功获取图片", content = @Content(mediaType = MediaType.IMAGE_JPEG_VALUE)),
                    @ApiResponse(responseCode = "404", description = "图片未找到", content = @Content)
            })
    public ResponseEntity<byte[]> getImage(@Parameter(description = "要获取的图片文件名", required = true) @PathVariable String fileName) {
        Path filePath = Paths.get(UPLOAD_DIR, fileName);
        File file = filePath.toFile();
        if (file.exists() && file.isFile()) {
            try {
                byte[] imageBytes = Files.readAllBytes(filePath);
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.IMAGE_JPEG);
                headers.setContentLength(imageBytes.length);
                return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
    }

    /**
     * 获取所有图片的列表，返回文件名数组
     * @return 返回包含所有图片文件名的响应实体
     */
    @GetMapping("/list")
    @Operation(summary = "获取所有图片列表", description = "返回存储的所有图片的文件名数组",
            responses = {
                    @ApiResponse(responseCode = "200", description = "成功获取图片列表", content = @Content(schema = @Schema(implementation = String[].class))),
                    @ApiResponse(responseCode = "404", description = "未找到图片", content = @Content)
            })
    public ResponseEntity<String[]> listImages() {
        File uploadDir = new File(UPLOAD_DIR);
        if (uploadDir.exists() && uploadDir.isDirectory()) {
            String[] imageFiles = uploadDir.list(new java.io.FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return name.startsWith("image") && name.endsWith(".jpg");
                }
            });
            if (imageFiles != null) {
                return ResponseEntity.ok(imageFiles);
            }
        }
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
    }
}